#include "stdafx.h"
#include "RAWReader.h"
#include "GL/freeglut.h"
#include "Resource.h"



MCVector*  RAWReader::ReadRawFile(string filename, int &cellH, int &cellW, int &cellF, float threshold1, float threshold2)
{
	ifstream myFile(filename, 
		ios::in | ios::binary);
	int frames;
	myFile.read((char*)&frames, sizeof(frames));
	
	int width;
	myFile.read((char*)&width, sizeof(int));

	int height;
	myFile.read((char*)&height, sizeof(int));
	int max=0;
	unsigned short* voxels=new unsigned short[width*height*frames];//short 2 bytes=16 bits
	mVoxels=new unsigned short[width*height*frames];//short 2 bytes=16 bits
	int index=0;
	for (int k=0; k<frames; k++)
	{
		for (int j=0; j<height; j++)
		{
			for (int i=0; i<width;i++)
			{
				myFile.read((char*)&voxels[index], sizeof(unsigned short));
				if(voxels[index]>max) max=voxels[index];
				index++;
			}
		}
	}
	myFile.close();

	unsigned int num[256]={0};

	index=0;
	int max2=0;
	for (int k=0; k<frames; k++)
	{
		for (int j=0; j<height; j++)
		{
			for (int i=0; i<width;i++)
			{
				voxels[index]=((float)(voxels[index]))*255/max;//normalize intensities to 8 bit format.
				mVoxels[index]=voxels[index];
				if(voxels[index]>max2) max2=voxels[index];
				num[voxels[index]]++;
				//thresholding
				if (voxels[index]>threshold1&&voxels[index]<=threshold2)
				{
					voxels[index]=150;
				}
				else if (voxels[index]>threshold2)
				{
					voxels[index]=250;
				}
				else
				{
					voxels[index]=0;
				}
				index++;
			}
		}
	}
	vector<unsigned int> v;
	for(int i=0;i<256;i++)
	{
		v.push_back(num[i]);
	}

	//use a 8 times smaller array to store the voxels in order to reduce memory usage.
	//unsigned short* mVoxels=new unsigned short[width*height*frames/8];
	//for (int k=0; k<frames/2; k++)
	//{
	//	for (int j=0; j<height/2; j++)
	//	{
	//		for (int i=0; i<width/2;i++)
	//		{
	//			mVoxels[k*width*height/4+j*width/2+i]=(voxels[(k*2)*width*height+(j*2)*width+(i*2)]
	//			+voxels[(k*2)*width*height+(j*2+1)*width+(i*2)]+voxels[(k*2)*width*height+(j*2)*width+(i*2+1)]+
	//				voxels[(k*2+1)*width*height+(j*2)*width+(i*2)]+voxels[(k*2)*width*height+(j*2+1)*width+(i*2+1)]+
	//				voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2+1)]+voxels[(k*2+1)*width*height+(j*2)*width+(i*2+1)]
	//			+voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2)])/8;//the value of every voxel is an average of vertices of a cube.
	//		}
	//	}
	//}

	//delete[] voxels;

	MCVector* vertices=new MCVector[width*height*frames/8];

	//store the voxels into vector structures.
	unsigned int idx=0;
	for (int k=0; k<frames/2; k++)
	{
		for (int j=0; j<height/2; j++)
		{
			for (int i=0; i<width/2;i++)
			{
				vertices[idx].x=j*2;
				vertices[idx].y=i*2;
				vertices[idx].z=k*2;
				vertices[idx].val=(voxels[(k*2)*width*height+(j*2)*width+(i*2)]
				+voxels[(k*2)*width*height+(j*2+1)*width+(i*2)]+voxels[(k*2)*width*height+(j*2)*width+(i*2+1)]+
					voxels[(k*2+1)*width*height+(j*2)*width+(i*2)]+voxels[(k*2)*width*height+(j*2+1)*width+(i*2+1)]+
					voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2+1)]+voxels[(k*2+1)*width*height+(j*2)*width+(i*2+1)]
				+voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2)])/8;
				idx++;
			}
		}
	}

	delete[] voxels;

	
	cellW=width/2;
	cellH=height/2;
	cellF=frames/2;

	return vertices;

}



MCVector* RAWReader::ReadRawFileWithProgress(HWND hwndParent, HINSTANCE g_hinst, string filename, int &cellH, int &cellW, int &cellF, float threshold1, float threshold2) 
{ 
	RECT rcClient;  // Client area of parent window.
	HWND hwndPB;    // Handle of progress bar.
	INITCOMMONCONTROLSEX iccInit;
	int iSpacing;   // Controls the size of the progress bar.
	
	// Initialize the common controls.
	iccInit.dwSize = sizeof(iccInit);
	iccInit.dwICC = ICC_PROGRESS_CLASS;
	InitCommonControlsEx(&iccInit);
	
	GetClientRect(hwndParent, &rcClient); 
	iSpacing = (int)(0.2 * (rcClient.right - rcClient.left));

	//Progress Bar
	hwndPB = CreateWindowEx(NULL,
		PROGRESS_CLASS, TEXT("Progress Bar"), 
		WS_CHILD | WS_VISIBLE
		//| WS_OVERLAPPED | WS_CAPTION
		,
		rcClient.left + iSpacing, 
		(int)((rcClient.bottom - rcClient.top)/2 - iSpacing/2),
		300,
		30, 
		hwndParent, (HMENU)1, g_hinst, NULL);

	// Open the file for reading, and retrieve the size of the file. 

	ifstream myFile(filename, 
		ios::in | ios::binary);
	int frames;
	myFile.read((char*)&frames, sizeof(frames));

	int width;
	myFile.read((char*)&width, sizeof(int));

	int height;
	myFile.read((char*)&height, sizeof(int));
	

	float fileSize=12+width*height*frames*2;//size in bytes

	/*ShowWindow(hwndParent, 2);
	UpdateWindow(hwndParent);*/

	W=width;
	H=height;
	F=frames;
	


	int max=0;
	unsigned short* voxels=new unsigned short[width*height*frames];//short 2 bytes=16 bits

	delete []mVoxels;
	mVoxels=new unsigned short[width*height*frames];//short 2 bytes=16 bits
	int index=0;
	int t=(frames*3)/100;
	// Set the range and increment of the progress bar. 

	SendMessage(hwndPB,PBM_SETRANGE, 0,MAKELPARAM(0,100));
	SendMessage(hwndPB, PBM_SETSTEP, MAKEWPARAM(1, 0), 0);
	for (int k=0; k<frames; k++)
	{
		for (int j=0; j<height; j++)
		{
			for (int i=0; i<width;i++)
			{
				myFile.read((char*)&voxels[index], sizeof(unsigned short));
				if(voxels[index]>max) max=voxels[index];
				index++;
				
			}
		}
		if (k%t==0)
		{
			 SendMessage(hwndPB, PBM_STEPIT, 0, 0); 
			//SendMessage(hwndPB, PBM_SETPOS,k*frames/100,0L);
		}
		
	}
	myFile.close();
	

	

	unsigned int num[256]={0};

	index=0;
	int max2=0;
	for (int k=0; k<frames; k++)
	{
		for (int j=0; j<height; j++)
		{
			for (int i=0; i<width;i++)
			{
				mVoxels[index]=voxels[index];
				voxels[index]=((float)(voxels[index]))*255/max;//normalize intensities to 8 bit format.
				
				if(voxels[index]>max2) max2=voxels[index];
				num[voxels[index]]++;
				//thresholding
				if (voxels[index]>threshold1&&voxels[index]<=threshold2)
				{
					voxels[index]=150;
				}
				else if (voxels[index]>threshold2)
				{
					voxels[index]=250;
				}
				else
				{
					voxels[index]=0;
				}
				index++;
			}
		}
		if (k%t==0)
		{
			SendMessage(hwndPB, PBM_STEPIT, 0, 0); 
			//SendMessage(hwndPB, PBM_SETPOS,k*frames/100,0L);
		}
	}
	//histogram.
	/*vector<unsigned int> v;
	for(int i=0;i<256;i++)
	{
		v.push_back(num[i]);
	}
*/
	//use a 8 times smaller array to store the voxels in order to reduce memory usage.
	//unsigned short* mVoxels=new unsigned short[width*height*frames/8];
	//for (int k=0; k<frames/2; k++)
	//{
	//	for (int j=0; j<height/2; j++)
	//	{
	//		for (int i=0; i<width/2;i++)
	//		{
	//			mVoxels[k*width*height/4+j*width/2+i]=(voxels[(k*2)*width*height+(j*2)*width+(i*2)]
	//			+voxels[(k*2)*width*height+(j*2+1)*width+(i*2)]+voxels[(k*2)*width*height+(j*2)*width+(i*2+1)]+
	//				voxels[(k*2+1)*width*height+(j*2)*width+(i*2)]+voxels[(k*2)*width*height+(j*2+1)*width+(i*2+1)]+
	//				voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2+1)]+voxels[(k*2+1)*width*height+(j*2)*width+(i*2+1)]
	//			+voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2)])/8;//the value of every voxel is an average of vertices of a cube.
	//		}
	//	}
	//}

	//delete[] voxels;

	MCVector* vertices=new MCVector[width*height*frames/8];

	//store the voxels into vector structures.
	unsigned int idx=0;
	for (int k=0; k<frames/2; k++)
	{
		for (int j=0; j<height/2; j++)
		{
			for (int i=0; i<width/2;i++)
			{
				vertices[idx].x=j*2;
				vertices[idx].y=i*2;
				vertices[idx].z=k*2;
				vertices[idx].val=(voxels[(k*2)*width*height+(j*2)*width+(i*2)]
				+voxels[(k*2)*width*height+(j*2+1)*width+(i*2)]+voxels[(k*2)*width*height+(j*2)*width+(i*2+1)]+
					voxels[(k*2+1)*width*height+(j*2)*width+(i*2)]+voxels[(k*2)*width*height+(j*2+1)*width+(i*2+1)]+
					voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2+1)]+voxels[(k*2+1)*width*height+(j*2)*width+(i*2+1)]
				+voxels[(k*2+1)*width*height+(j*2+1)*width+(i*2)])/8;
				idx++;
			}
		}
		if (k%t==0)
		{
			SendMessage(hwndPB, PBM_STEPIT, 0, 0); 
			//SendMessage(hwndPB, PBM_SETPOS,k*frames/100,0L);
		}
	}

	delete[] voxels;

	SendMessage(hwndPB, PBM_SETPOS, MAKELPARAM(100, 0), 0); 
	cellW=width/2;
	cellH=height/2;
	cellF=frames/2;
	DestroyWindow(hwndPB);
	return vertices;
}



